# -*- coding: utf-8 -*-
import os
import time
import psutil
import smtplib
from datetime import datetime
from email.mime.text import MIMEText
from email.utils import formataddr

import docker
from loguru import logger


def send_email(subject, message, config, last_notification_time):
    try:
        # 检查是否在通知冷却期内
        now = time.time()
        last_time = last_notification_time.get(subject, 0)
        if (now - last_time) < config.get('notification_cooldown', 3600):
            return

        msg = MIMEText(message)
        msg['Subject'] = subject
        msg['From'] = formataddr((config['email']['sender_name'], config['email']['sender']))
        msg['To'] = config['email']['receiver']

        with smtplib.SMTP(config['email']['smtp_server'], config['email']['smtp_port']) as server:
            server.login(config['email']['sender'], config['email']['password'])
            server.send_message(msg)

        logger.info(f"已发送通知邮件: {subject}")
        last_notification_time[subject] = now
    except Exception as e:
        logger.error(f"发送邮件失败: {e}")


class SystemMonitor:
    def __init__(self, config):
        """初始化监控器"""
        self.config = config
        self.last_notification_time = {}

    def check_python_program(self, program_name):
        """检查指定的Python程序是否在运行"""
        try:
            # 预处理程序名，移除可能的路径和扩展名
            program_name = os.path.basename(program_name).replace('.py', '')

            for proc in psutil.process_iter(['name', 'cmdline']):
                if program_name in ' '.join(proc.info['cmdline'] or []):
                    return True
            return False

        except Exception as e:
            logger.error(f"检查Python程序 '{program_name}' 失败: {str(e)}", exc_info=True)
            return False

    def run_monitoring(self):
        logger.info("启动监控系统...")

        while True:
            current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            logger.info(f"\n[{current_time}] 执行监控检查...")

            # 检查Python主程序
            if self.config['monitor_python_programs']:
                for program in self.config['python_programs_to_monitor']:
                    if not self.check_python_program(program['name']):
                        subject = f"警报: Python程序 {program['name']} 已停止运行!"
                        message = f"Python程序 {program['name']} 未在运行。请立即检查系统状态。\n检测时间: {current_time}"
                        send_email(subject, message, self.config, self.last_notification_time)
                        logger.warning(f"Python程序 {program['name']} 状态: 异常")
                    else:
                        logger.info(f"Python程序 {program['name']} 状态: 正常")

            # 等待下一次检查
            time.sleep(self.config['check_interval_seconds'])


# 配置示例
config = {
    # 监控设置
    'monitor_python_programs': True,

    # 要监控的Python程序列表
    'python_programs_to_monitor': [
        {'name': "upload_gb_data"}
    ],

    # 检查间隔(秒)
    'check_interval_seconds': 60,

    # 通知冷却时间(秒)，避免短时间内重复发送相同警报
    'notification_cooldown': 3600,

    # 邮件配置
    'email': {
        'smtp_server': 'smtp.126.com',
        'smtp_port': 25,
        'use_tls': True,
        'sender': 'wu_319@126.com',
        "sender_name": '水科院服务器_monitor',  # portAI-monitor
        'password': 'TUg6wbkD7zpMdZ6a',
        'receiver': '1421874933@qq.com'
    }
}

if __name__ == "__main__":
    # monitor = SystemMonitor(config)
    # monitor.run_monitoring()

    current_time = time.time()
    last_notification_time = {}
    subject = f"警报: Python程序 aaa 已停止运行!"
    message = f"Python程序 aaa 未在运行。请立即检查系统状态。\n*检测时间*: {current_time}"
    send_email(subject, message, config, last_notification_time)
